/**
 * Copyright (C)  2011  chen wei hua.
 * Permission is granted to copy, distribute and/or modify this document
 * under the terms of the GNU Free Documentation License, Version 2.0
 * or any later version published by the Free Software Foundation;
 * with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
 * A copy of the license is included in the section entitled "GNU Free Documentation License".
 */
package com.javaeye.store.web;

import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;

import com.opensymphony.xwork2.ActionSupport;
import com.javaeye.common.util.DateUtils;
import com.javaeye.common.util.ExcelUtil;
import com.javaeye.common.util.ListItem;
import com.javaeye.common.util.ListUtil;
import com.javaeye.common.web.PageInfo;
import com.javaeye.store.dto.Materials;
import com.javaeye.store.dto.MaterialsCategory;
import com.javaeye.store.dto.MaterialsField;
import com.javaeye.store.dto.MaterialsFieldCustom;
import com.javaeye.store.dto.MaterialsSKUDetail;
import com.javaeye.common.service.ICodeService;
import com.javaeye.store.service.IMaterialsCategoryService;
import com.javaeye.store.service.IMaterialsFieldService;
import com.javaeye.store.service.IMaterialsService;

public class MaterialsAction extends ActionSupport {
	
	protected static Log log = LogFactory.getLog(MaterialsAction.class); 
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -3216585574200112708L;

	/**
	 * 用于显示一览结果集
	 */
	private List<Materials> materialsList;
	
	/**
	 * 用于接收分页值对象
	 */
	private PageInfo pageInfo;
	
	/**
	 * 用于接收查询条件值对象
	 */
	private Materials condition;
	
	/**
	 * 用于接收添加画面和编辑画面的值对象
	 */
	private Materials materials;
	
	/**
	 * 用于接收需要修改和删除的ID值
	 */
	private String materialsId;
	
	/**
	 * 用于生成查询画面上选择分类的下拉框的值
	 */
	private List<MaterialsCategory> rootCategoryList;
	
	/**
	 * 用于生成查询画面上选择分类的下拉框的值
	 */
	private List<MaterialsCategory> categoryList;
	
	/**
	 * 用于生成查询画面上选择名称的下拉框的值
	 */
	private List<MaterialsCategory> nameList;
	
	/**
	 * 用于生成查询画面上选择单位的下拉框的值
	 */
	private List<ListItem> unitsList;
	
	
	/**
	 * 应用autocomplete的查询使用接口
	 */
	private String q;
	
	private InputStream excelStream;
	
	private File excelFile;
	
	/**
	 * 用于配置供应商属性的list
	 */
	private List<MaterialsField> supplierFileList;
	
	/**
	 * 已经选中的供应商属性list
	 */
	private Set<MaterialsFieldCustom> supplierSelectFileList;
	
	/**
	 * 供应商属性的list选中状态
	 */
	private Set<String> supplierFileValues;
	
	/**
	 * 用于配置客户属性的list
	 */
	private List<MaterialsField> customerFileList;
	
	/**
	 * 已经选中的客户属性list
	 */
	private Set<MaterialsFieldCustom> customerSelectFileList;
	
	/**
	 * 客户属性的list选中状态
	 */
	private Set<String> customerFileValues;
	
	/**
	 * 用于配置颜色属性的list
	 */
	private List<MaterialsField> colorFileList;
	
	/**
	 * 已经选中的颜色属性list
	 */
	private Set<MaterialsFieldCustom> colorSelectFileList;
	
	/**
	 * 颜色属性的list选中状态
	 */
	private Set<String> colorFileValues;
	
	/**
	 * 自定义属性ID
	 */
	private List<String> fileCustomIds;
	
	/**
	 * 自定义属性值
	 */
	private List<String> fileCustomValues;
	
	/**
	 * sku配置供应商属性ID
	 */
	private List<String> skuConfigSupplierIds;
	
	/**
	 * sku配置供应商属性RowID
	 */
	private List<Integer> skuConfigSupplierIdrows;
	
	/**
	 * sku配置客户属性ID
	 */
	private List<String> skuConfigCustomerIds;
	
	/**
	 * sku配置客户属性RowID
	 */
	private List<Integer> skuConfigCustomerIdrows;
	
	/**
	 * sku配置颜色属性ID
	 */
	private List<String> skuConfigColorIds;
	
	/**
	 * sku配置颜色属性RowID
	 */
	private List<Integer> skuConfigColorIdrows;
	
	private IMaterialsFieldService materialsFieldService;
	
	/**
	 * Service
	 */
	private IMaterialsService service;
	
	private IMaterialsCategoryService categoryService;
	
	private ICodeService codeService;
	
	public void setService(IMaterialsService service) {
		this.service = service;
	}

	public void setCategoryService(IMaterialsCategoryService categoryService) {
		this.categoryService = categoryService;
	}
	
	public void setCodeService(ICodeService codeService) {
		this.codeService = codeService;
	}
	
	public void setMaterialsFieldService(
			IMaterialsFieldService materialsFieldService) {
		this.materialsFieldService = materialsFieldService;
	}

	public MaterialsAction() {
		pageInfo = new PageInfo();
		pageInfo.setPageIndex(0);
		condition = new Materials();
		condition.setName("");
		condition.setCode("");
		condition.getCategory().setId(-1);
		condition.getRootCategory().setId(-1);
		condition.setType("");
	}
	
	public String queryMaterialsNames() throws Exception {
		materialsList = service.getAutoCompleteMaterials(q, 10);
		return SUCCESS;
	}
	
	/**
	 * 条件分页查询
	 * @return
	 * @throws Exception
	 */
	public String queryMaterialsList() throws Exception {
		//log.debug("currentPage=" + pageInfo.getPageIndex() + 
		//		", category=" + condition.getCategory() + 
		//		", name=" + condition.getName());
		rootCategoryList = categoryService.getCategorys(0);
		categoryList = categoryService.getCategorys(condition.getRootCategory().getId());
		nameList = categoryService.getCategorys(condition.getCategory().getId());
		materialsList = service.getMaterialsList(condition, pageInfo);
		return SUCCESS;
	}
	
	/**
	 * 取得当前SKU配置信息
	 * @param configValues
	 * @param fieldRowIndexs
	 * @param fieldIds
	 * @param parentId
	 */
	private void initDetailField(Map<Integer, MaterialsSKUDetail> configValues,
			List<Integer> fieldRowIndexs, List<String> fieldIds, String parentId) {
		if (fieldIds != null && fieldIds.size() > 0) {
			for (int i = 0; i < fieldIds.size(); i++) {
				int rowIndex = fieldRowIndexs.get(i);
				MaterialsSKUDetail detail = configValues.get(rowIndex);
				if (detail == null) {
					detail = new MaterialsSKUDetail();
					detail.setInuse(1);
					configValues.put(rowIndex, detail);
				}
				MaterialsField f = new MaterialsField();
				f.setFieldGroupId(parentId);
				f.setId(fieldIds.get(i));
				detail.addField(f);
			}
		}
	}
	
	/**
	 * 保存物料
	 * @return
	 * @throws Exception
	 */
	public String saveMaterials() throws Exception {
		Map<Integer, MaterialsSKUDetail> configValues = new HashMap<Integer, MaterialsSKUDetail>();
		initDetailField(configValues, skuConfigSupplierIdrows, skuConfigSupplierIds, ListUtil.FIELD_GROUP_SUPPLIER);
		initDetailField(configValues, skuConfigCustomerIdrows, skuConfigCustomerIds, ListUtil.FIELD_GROUP_CUSTOMER);
		initDetailField(configValues, skuConfigColorIdrows, skuConfigColorIds, ListUtil.FIELD_GROUP_COLOR);
		
		//判断是否有重复的SKU配置
		Set<String> fieldComboxs = new HashSet<String>();
		Collection<MaterialsSKUDetail> values = configValues.values();
		for (MaterialsSKUDetail detail : values) {
			String combox = detail.getFieldCombox();
			if (!fieldComboxs.contains(combox)) {
				fieldComboxs.add(combox);
				materials.addSkuDetail(detail);
			} else {
				List<Object> params = new ArrayList<Object>();
				params.add("SKU配置");
				this.addActionError(getText("actionErrorSaveSameRecord", params));
				queryMaterialsForEdit();
				return INPUT;
			}
		}
		
		//取得当前SKU自定义列信息
		if (fileCustomIds != null && fileCustomIds.size() > 0) {
			for (int i = 0; i < fileCustomIds.size(); i++) {
				MaterialsFieldCustom customField = new MaterialsFieldCustom();
				customField.setFieldId(fileCustomIds.get(i));
				customField.setValue(fileCustomValues.get(i));
				customField.setInuse(1);
				materials.addCustomField(customField);
			}
		}
		boolean success = service.saveMaterials(materialsId, materials);
		if (!success) {
			List<Object> params = new ArrayList<Object>();
			params.add("物料");
			this.addActionError(getText("actionErrorSaveUNIQUE", params));
			queryForAddMaterials();
			return INPUT;
		}
		return SUCCESS;
	}
	
	/**
	 * 查询物料
	 * @return
	 * @throws Exception
	 */
	public String queryMaterialsForEdit() throws Exception {
		rootCategoryList = categoryService.getCategorys(0);
		unitsList = ListUtil.baseCodeList(codeService, ListUtil.UNIT_CODE_CATEGORY);
		materials = service.getMaterials(materialsId);
		categoryList = categoryService.getCategorys(materials.getRootCategory().getId());
		nameList = categoryService.getCategorys(materials.getCategory().getId());
		
		supplierFileList = materialsFieldService.getFields(ListUtil.FIELD_GROUP_SUPPLIER);
		customerFileList = materialsFieldService.getFields(ListUtil.FIELD_GROUP_CUSTOMER);
		colorFileList = materialsFieldService.getFields(ListUtil.FIELD_GROUP_COLOR);
		
		//去除不需要显示的SKU配置
		Set<MaterialsSKUDetail> skuDetails = materials.getSkuDetails();
		for (Iterator<MaterialsSKUDetail> i = skuDetails.iterator(); i.hasNext();) { 
			MaterialsSKUDetail element = i.next(); 
		    if (element.getInuse() == 0) {
		        i.remove(); 
		    } 
		}
		initSkuConfigIds(skuDetails);
		
		return SUCCESS;
	}
	
	/**
	 * 初始化SKU配制信息和自定义列信息
	 * @param skuDetails
	 */
	private void initSkuConfigIds(Set<MaterialsSKUDetail> skuDetails) {
		supplierFileValues = new HashSet<String>();
		customerFileValues = new HashSet<String>();
		colorFileValues = new HashSet<String>();
		supplierSelectFileList = new HashSet<MaterialsFieldCustom>();
		customerSelectFileList = new HashSet<MaterialsFieldCustom>();
		colorSelectFileList = new HashSet<MaterialsFieldCustom>();
		
		for (MaterialsSKUDetail detail : skuDetails) {
			List<MaterialsField> fields = detail.getFields();
			for (MaterialsField field : fields) {
				if (ListUtil.FIELD_GROUP_SUPPLIER.equals(field.getFieldGroupId())) {
					supplierFileValues.add(field.getId());
					MaterialsFieldCustom customField = getCustomField(materials, field.getId());
					field.setCustomName(customField.getValue());
					customField.setDefaultValue(getFieldValue(field.getId(), supplierFileList));
					supplierSelectFileList.add(customField);
				} else if (ListUtil.FIELD_GROUP_CUSTOMER.equals(field.getFieldGroupId())) {
					customerFileValues.add(field.getId());
					MaterialsFieldCustom customField = getCustomField(materials, field.getId());
					field.setCustomName(customField.getValue());
					customField.setDefaultValue(getFieldValue(field.getId(), customerFileList));
					customerSelectFileList.add(customField);
				} else if (ListUtil.FIELD_GROUP_COLOR.equals(field.getFieldGroupId())) {
					colorFileValues.add(field.getId());
					MaterialsFieldCustom customField = getCustomField(materials, field.getId());
					field.setCustomName(customField.getValue());
					customField.setDefaultValue(getFieldValue(field.getId(), colorFileList));
					colorSelectFileList.add(customField);
				}
			}
		}
	}
	
	/**
	 * 根据字段ID找出自定义字段
	 * @param materials
	 * @param fieldId
	 * @return
	 */
	private MaterialsFieldCustom getCustomField(Materials materials, String fieldId) {
		Set<MaterialsFieldCustom> customFields = materials.getCustomFields();
		for (MaterialsFieldCustom f : customFields) {
			if (fieldId.equals(f.getFieldId())) {
				return f;
			}
		}
		return new MaterialsFieldCustom();
	}
	
	/**
	 * 取得字段ID对应值
	 * @param fieldId
	 * @param fields
	 * @return
	 */
	private String getFieldValue(String fieldId, List<MaterialsField> fields) {
		for (MaterialsField f : fields) {
			if (fieldId.equals(f.getId())) {
				return f.getName();
			}
		}
		return "";
	}
	
	/**
	 * 查询用于添加物料
	 * @return
	 * @throws Exception
	 */
	public String queryForAddMaterials() throws Exception {
		rootCategoryList = categoryService.getCategorys(0);
		unitsList = ListUtil.baseCodeList(codeService, ListUtil.UNIT_CODE_CATEGORY);
		categoryList = new ArrayList<MaterialsCategory>();
		nameList = new ArrayList<MaterialsCategory>();
		
		supplierFileList = materialsFieldService.getFields(ListUtil.FIELD_GROUP_SUPPLIER);
		customerFileList = materialsFieldService.getFields(ListUtil.FIELD_GROUP_CUSTOMER);
		colorFileList = materialsFieldService.getFields(ListUtil.FIELD_GROUP_COLOR);
		
		return SUCCESS;
	}
	
	/**
	 * 删除物料
	 * @return
	 * @throws Exception
	 */
	public String deleteMaterials() throws Exception {
		boolean result = service.removeMaterials(materialsId);
		queryMaterialsList();
		if (!result) {
			List<Object> params = new ArrayList<Object>();
			params.add("物料");
			this.addActionError(getText("actionErrorDeleteFK", params));
			return INPUT;
		}
		return SUCCESS;
	}
	
	@SuppressWarnings("unchecked")
	public String exportExcel() throws Exception {
		List<Materials> materialsList = service.getMaterialsExportList(condition);
		List materialsListExcel = new ArrayList<MaterialsSKUDetail>();
		for (Materials m : materialsList) {
			Set<MaterialsSKUDetail> skuDetails = m.getSkuDetails();
			for (MaterialsSKUDetail skuDetail : skuDetails) {
				if (skuDetail.getInuse() == 1) {
					materialsListExcel.add(skuDetail);
				}
			}
		}
		excelStream = ExcelUtil.workbook2InputStream(
				ExcelUtil.getWorkbook(materialsListExcel));
		return SUCCESS;
	}
	
	public String importExcel() throws Exception {
        Workbook book = ExcelUtil.createWorkBook(excelFile);  
        //book.getNumberOfSheets();  判断Excel文件有多少个sheet   
        Sheet sheet =  book.getSheetAt(0);
        //Row firstRow = sheet.getRow(0);
        
        List<Object[]> datas = new ArrayList<Object[]>();
        for (int i = 1; i <= sheet.getLastRowNum(); i++) {  
            Row ros = sheet.getRow(i);
            Object[] m = initMaterialData(ros);
            if (m[2] == null || "".equals(m[2].toString().trim())) {
            	this.addActionError("批号未输入， code=" + m[0]);
            	return INPUT;
            }
            datas.add(m);  
        }
        
        //is.close();
        service.saveImportMaterials(datas);
        this.addActionMessage("导入成功！");
        return SUCCESS;
	}
	
	private Object[] initMaterialData(Row ros) {
		Object[] m = new Object[6]; 
		m[0] = ((int)ExcelUtil.getNumber(ros, 6));//category
		m[1] = ((int)ExcelUtil.getNumber(ros, 7));//ID
		m[2] = (ExcelUtil.getString(ros, 8));//批号
		m[3] = (ExcelUtil.getNumber(ros, 9));//价格
		m[4] = ((float)ExcelUtil.getNumber(ros, 10));//合格数
		m[5] = ((float)ExcelUtil.getNumber(ros, 11));//不合格数
		return m;
	}
	
	public InputStream getExcelStream() {
		return excelStream;
	}

	public void setExcelStream(InputStream excelStream) {
		this.excelStream = excelStream;
	}

	public String getFileName() {
		String now = DateUtils.dateToString("yyyyMMddHHmmss");
		return "materialsList_" + now;
	}

	public List<Materials> getMaterialsList() {
		return materialsList;
	}

	public void setMaterialsList(List<Materials> materialsList) {
		this.materialsList = materialsList;
	}

	public PageInfo getPageInfo() {
		return pageInfo;
	}

	public void setPageInfo(PageInfo pageInfo) {
		this.pageInfo = pageInfo;
	}

	public Materials getCondition() {
		return condition;
	}

	public void setCondition(Materials condition) {
		this.condition = condition;
	}

	public Materials getMaterials() {
		return materials;
	}

	public void setMaterials(Materials materials) {
		this.materials = materials;
	}

	public String getMaterialsId() {
		return materialsId;
	}

	public void setMaterialsId(String materialsId) {
		this.materialsId = materialsId;
	}

	public List<MaterialsCategory> getCategoryList() {
		return categoryList;
	}

	public void setCategoryList(List<MaterialsCategory> categoryList) {
		this.categoryList = categoryList;
	}

	public String getQ() {
		return q;
	}

	public void setQ(String q) {
		this.q = q;
	}

	public void setUnitsList(List<ListItem> unitsList) {
		this.unitsList = unitsList;
	}

	public List<ListItem> getUnitsList() {
		return unitsList;
	}

	public void setNameList(List<MaterialsCategory> nameList) {
		this.nameList = nameList;
	}

	public List<MaterialsCategory> getNameList() {
		return nameList;
	}

	public void setRootCategoryList(List<MaterialsCategory> rootCategoryList) {
		this.rootCategoryList = rootCategoryList;
	}

	public List<MaterialsCategory> getRootCategoryList() {
		return rootCategoryList;
	}

	public void setExcelFile(File excelFile) {
		this.excelFile = excelFile;
	}

	public File getExcelFile() {
		return excelFile;
	}

	public List<MaterialsField> getSupplierFileList() {
		return supplierFileList;
	}

	public void setSupplierFileList(List<MaterialsField> supplierFileList) {
		this.supplierFileList = supplierFileList;
	}

	public Set<String> getSupplierFileValues() {
		return supplierFileValues;
	}

	public void setSupplierFileValues(Set<String> supplierFileValues) {
		this.supplierFileValues = supplierFileValues;
	}

	public List<MaterialsField> getCustomerFileList() {
		return customerFileList;
	}

	public void setCustomerFileList(List<MaterialsField> customerFileList) {
		this.customerFileList = customerFileList;
	}

	public Set<String> getCustomerFileValues() {
		return customerFileValues;
	}

	public void setCustomerFileValues(Set<String> customerFileValues) {
		this.customerFileValues = customerFileValues;
	}

	public List<MaterialsField> getColorFileList() {
		return colorFileList;
	}

	public void setColorFileList(List<MaterialsField> colorFileList) {
		this.colorFileList = colorFileList;
	}

	public Set<String> getColorFileValues() {
		return colorFileValues;
	}

	public void setColorFileValues(Set<String> colorFileValues) {
		this.colorFileValues = colorFileValues;
	}

	public List<String> getFileCustomIds() {
		return fileCustomIds;
	}

	public void setFileCustomIds(List<String> fileCustomIds) {
		this.fileCustomIds = fileCustomIds;
	}

	public List<String> getFileCustomValues() {
		return fileCustomValues;
	}

	public void setFileCustomValues(List<String> fileCustomValues) {
		this.fileCustomValues = fileCustomValues;
	}

	public List<String> getSkuConfigSupplierIds() {
		return skuConfigSupplierIds;
	}

	public void setSkuConfigSupplierIds(List<String> skuConfigSupplierIds) {
		this.skuConfigSupplierIds = skuConfigSupplierIds;
	}

	public List<String> getSkuConfigCustomerIds() {
		return skuConfigCustomerIds;
	}

	public void setSkuConfigCustomerIds(List<String> skuConfigCustomerIds) {
		this.skuConfigCustomerIds = skuConfigCustomerIds;
	}

	public List<String> getSkuConfigColorIds() {
		return skuConfigColorIds;
	}

	public void setSkuConfigColorIds(List<String> skuConfigColorIds) {
		this.skuConfigColorIds = skuConfigColorIds;
	}

	public Set<MaterialsFieldCustom> getSupplierSelectFileList() {
		return supplierSelectFileList;
	}

	public void setSupplierSelectFileList(
			Set<MaterialsFieldCustom> supplierSelectFileList) {
		this.supplierSelectFileList = supplierSelectFileList;
	}

	public Set<MaterialsFieldCustom> getCustomerSelectFileList() {
		return customerSelectFileList;
	}

	public void setCustomerSelectFileList(
			Set<MaterialsFieldCustom> customerSelectFileList) {
		this.customerSelectFileList = customerSelectFileList;
	}

	public Set<MaterialsFieldCustom> getColorSelectFileList() {
		return colorSelectFileList;
	}

	public void setColorSelectFileList(Set<MaterialsFieldCustom> colorSelectFileList) {
		this.colorSelectFileList = colorSelectFileList;
	}

	public List<Integer> getSkuConfigSupplierIdrows() {
		return skuConfigSupplierIdrows;
	}

	public void setSkuConfigSupplierIdrows(List<Integer> skuConfigSupplierIdrows) {
		this.skuConfigSupplierIdrows = skuConfigSupplierIdrows;
	}

	public List<Integer> getSkuConfigCustomerIdrows() {
		return skuConfigCustomerIdrows;
	}

	public void setSkuConfigCustomerIdrows(List<Integer> skuConfigCustomerIdrows) {
		this.skuConfigCustomerIdrows = skuConfigCustomerIdrows;
	}

	public List<Integer> getSkuConfigColorIdrows() {
		return skuConfigColorIdrows;
	}

	public void setSkuConfigColorIdrows(List<Integer> skuConfigColorIdrows) {
		this.skuConfigColorIdrows = skuConfigColorIdrows;
	}

}
